#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "estructuras.h"
#include "constantes.h"
#include "listas.h"


int	AgregarAColaGlobal(struct ListaIDdescriptors ** pnodo, struct ListaIDdescriptors ** ListaDeIDPedidos, struct ListaIDdescriptors ** ListaDeIDPedidos_Ult )
{

	if((*ListaDeIDPedidos) == NULL)
	{
		(*pnodo)->Ant = NULL;
		(*pnodo)->Sgt = NULL;
		(*ListaDeIDPedidos) = (*pnodo);
	}	
	else
	{
		(*pnodo)->Ant = *ListaDeIDPedidos_Ult;	
		(*pnodo)->Sgt = NULL;
		(*ListaDeIDPedidos_Ult)->Sgt = (*pnodo);
	}
	
	*ListaDeIDPedidos_Ult=*pnodo;

}



int agregarAListaDeDiscos(struct DiscoConocido ** pnodo)			/*Agrega el nodo a la lista ListaDiscos (enlazar) */
{

	if((ListaDiscos) == NULL)
	{
		(*pnodo)->Ant = NULL;
		(*pnodo)->Sgt = NULL;
		ListaDiscos = (*pnodo);
	}	
	else
	{
		(*pnodo)->Ant = ListaDiscos_Ult;	
		(*pnodo)->Sgt = NULL;
		ListaDiscos_Ult->Sgt = (*pnodo);
	}
	
	ListaDiscos_Ult=*pnodo;


}



int agregarAListaDeClientes(cliente ** pnodo)			/*Agrega el nodo a la lista ListaDiscos (enlazar) */
{


	if((ListaClientes) == NULL)
	{
		(*pnodo)->Ant = NULL;
		(*pnodo)->Sgt = NULL;
		ListaClientes = (*pnodo);
	}	
	else
	{
		(*pnodo)->Ant = ListaClientes_Ult;	
		(*pnodo)->Sgt = NULL;
		ListaClientes_Ult->Sgt = (*pnodo);
	}
	
	ListaClientes_Ult=*pnodo;

}






struct ListaIDdescriptors * SacarNodoDescriptoresDeLista(struct ListaIDdescriptors ** ListaDeIDPedidos, struct ListaIDdescriptors ** ListaDeIDPedidos_Ult)
{
	struct ListaIDdescriptors * temp;
	
	temp=*ListaDeIDPedidos;
	*ListaDeIDPedidos=(*ListaDeIDPedidos)->Sgt;
	if(*ListaDeIDPedidos == NULL){
      *ListaDeIDPedidos_Ult=NULL;
	}
	return temp;
	
}



struct DiscoConocido * BuscarDiscoPorNombre(char * sNombreDiscoABuscar)		/* busca disco por sNombre, y devuelve el nodo, NULL si no lo encuentra*/
{
	struct DiscoConocido * pNodo;

	pNodo = ListaDiscos;

	while(pNodo != NULL)
	{
		if(!(strcmp(pNodo->sNombre , sNombreDiscoABuscar)))
			return pNodo;
		pNodo = pNodo->Sgt;
	}

	return NULL;

}



struct DiscoConocido * BuscarDiscoPorSocketParaDA(int iSocket)		
{

struct DiscoConocido * pNodo;
	
	
	pNodo = ListaDiscos;

	while(pNodo != NULL)
		{
		if(pNodo->iSocketHDAParaDA  == iSocket)
			return pNodo;
		pNodo = pNodo->Sgt;
		}

return NULL;

}






struct DiscoConocido * BuscarDiscoListo()	
{

struct DiscoConocido * pNodo;
	
	
	pNodo = ListaDiscos;

	while(pNodo != NULL)
		{
		if((pNodo->Estado == LISTO)||(pNodo->Estado == SINCRONIZANDO_LEYENDO))
			return pNodo;
		pNodo = pNodo->Sgt;
		}

return NULL;

}




int	SacarDeLista_DA(struct DiscoConocido ** nodo)  /*solo desenalzar el nodo de la lista ListaDA , sin liberar*/
{



if(  ((*nodo)->Ant == NULL) && ((*nodo)->Sgt == NULL)  )
	{
	ListaDiscos_Ult = NULL;
	ListaDiscos = NULL;

	}
else if(  ((*nodo)->Ant == NULL) && ((*nodo)->Sgt != NULL)  )
	{
	ListaDiscos = (*nodo)->Sgt;
	ListaDiscos->Ant = NULL;
	}

else if(  ((*nodo)->Ant != NULL) && ((*nodo)->Sgt == NULL)  )
	{

	ListaDiscos_Ult = (*nodo)->Ant;
	ListaDiscos_Ult->Sgt = NULL;

	}
else if(  ((*nodo)->Ant != NULL) && ((*nodo)->Sgt != NULL)  )
	{
	(*nodo)->Ant->Sgt=(*nodo)->Sgt;
	(*nodo)->Sgt->Ant=(*nodo)->Ant;

	}



return 0;

}



int	SacarDeLista_Clientes(cliente ** nodo)  /*solo desenalzar el nodo de la lista ListaDA , sin liberar*/
{

if(  ((*nodo)->Ant == NULL) && ((*nodo)->Sgt == NULL)  )
	{
	ListaClientes_Ult = NULL;
	ListaClientes = NULL;

	}
else if(  ((*nodo)->Ant == NULL) && ((*nodo)->Sgt != NULL)  )
	{
	ListaClientes = (*nodo)->Sgt;
	ListaClientes->Ant = NULL;
	}

else if(  ((*nodo)->Ant != NULL) && ((*nodo)->Sgt == NULL)  )
	{

	ListaClientes_Ult = (*nodo)->Ant;
	ListaClientes_Ult->Sgt = NULL;

	}
else if(  ((*nodo)->Ant != NULL) && ((*nodo)->Sgt != NULL)  )
	{
	(*nodo)->Ant->Sgt=(*nodo)->Sgt;
	(*nodo)->Sgt->Ant=(*nodo)->Ant;

	}



return 0;


}





int estaVacia(struct ListaIDdescriptors * ListaDeIDPedidos){

   return ListaDeIDPedidos==NULL;

}




int estaVacia2(disco * listaDiscos){

   return listaDiscos==NULL;

}


int longitud(struct ListaIDdescriptors *  ptrActual) {
	
	int n=0;
	
	while (ptrActual != NULL) {  
		++n;
		ptrActual = ptrActual->Sgt;
	}
	return n;

}


int longitud2(struct DiscoConocido *  ptrActual) {
	
	int n=0;
	
	while (ptrActual != NULL) {  
		if((ptrActual->Estado==LISTO) || (ptrActual->Estado=SINCRONIZANDO_LEYENDO)) 
			++n;
		ptrActual=ptrActual->Sgt;	
	}
	return n;

}


struct ListaIDdescriptors * BuscarDescriptorEnListaDeDisco(struct ListaIDdescriptors * ListaDeIDPedidos, char * sDescriptorIDABuscar)		//busca un la lista de descriptores del disco por opciones: (en este el sDescriptorID_delDA que sea igual sDescriptorID, y lo saca de la lista)

{
	struct ListaIDdescriptors * pNodo;
	pNodo = ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(!strcmp(pNodo->sDescriptorID_delPedido , sDescriptorIDABuscar)){
			return pNodo;	
		}	
		pNodo = pNodo->Sgt;
	}
	printf("NO SE ENCONTRO Descriptor\n");
	return NULL;

}



pedido * Buscar(pedido* ListaDeIDPedidos,pedido* ListaDeIDPedidos_Ult){


	pedido *pNodo = ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(((pNodo->operacion==3) && (pNodo->estado==-1))|| ((pNodo->operacion==4)&&(pNodo->estado==-1)))
			break;
		pNodo = pNodo->Sgt;
	}
	
	return pNodo;
}

	
int SacarNodoDescriptoresDeLista2(struct ListaIDdescriptors ** nodo, struct ListaIDdescriptors ** ListaDeIDPedidos, struct ListaIDdescriptors ** ListaDeIDPedidos_Ult)
{
	
	if(  ((*nodo)->Ant == NULL) && ((*nodo)->Sgt == NULL)  )
	{
		(*ListaDeIDPedidos_Ult) = NULL;
		(*ListaDeIDPedidos) = NULL;
	}
	else if(  ((*nodo)->Ant == NULL) && ((*nodo)->Sgt != NULL)  )
	{
		(*ListaDeIDPedidos) = (*nodo)->Sgt;
		(*ListaDeIDPedidos)->Ant = NULL;			
	}
	else if(  ((*nodo)->Ant != NULL) && ((*nodo)->Sgt == NULL)  )
	{
		(*ListaDeIDPedidos_Ult) = (*nodo)->Ant;
		(*ListaDeIDPedidos_Ult)->Sgt = NULL;					
	}
	else if(  ((*nodo)->Ant != NULL) && ((*nodo)->Sgt != NULL)  )
	{
		(*nodo)->Ant->Sgt=(*nodo)->Sgt;
		(*nodo)->Sgt->Ant=(*nodo)->Ant;
	}

	return 0;

}


int	AgregarAColaDePedidosADisco(struct ListaIDdescriptors ** pnodo, struct ListaIDdescriptors ** ListaDeIDPedidos, struct ListaIDdescriptors ** ListaDeIDPedidos_Ult )
{
	struct ListaIDdescriptors *anterior;
	struct ListaIDdescriptors *aux;
	
	if((*ListaDeIDPedidos) == NULL)
	{
		(*pnodo)->Ant = NULL;
		(*pnodo)->Sgt = NULL;
		(*ListaDeIDPedidos) = (*pnodo);
	}	
	else
	{
		(*pnodo)->Ant = *ListaDeIDPedidos_Ult;	
		(*pnodo)->Sgt = NULL;
		(*ListaDeIDPedidos_Ult)->Sgt = (*pnodo);
	}
	
	*ListaDeIDPedidos_Ult=*pnodo;
	
}

void imprimirCola(cliente *ptrActual){

   if(ptrActual==NULL)
      printf("La cola esta vacia\n");

   else{
   
		printf("La Cola es: \n");
		while(ptrActual!=NULL){ 
			printf("%i->",ptrActual->socketCliente);
			/*printf("data %s\n",ptrActual->data);*/
			ptrActual=ptrActual->Sgt;  
		}
		printf("NULL \n");  
   }
   
} 

void imprimirCola2(struct ListaIDdescriptors *ptrActual){

   if(ptrActual==NULL)
      printf("La cola esta vacia\n");

   else{
   
		printf("La Cola es: \n");
		while(ptrActual!=NULL){ 
			printf("%s->",ptrActual->sDescriptorID_delPedido);
			/*printf("%s->",ptrActual->data);*/
			/*printf("%s->",ptrActual->discoAsignado);*/
			/*printf("%i->",ptrActual->numeroSector);*/
			ptrActual=ptrActual->Sgt;  
		}
		printf("NULL \n");  
   }
   
} 




void imprimirCola3(struct ListaIDdescriptors *ptrActual){

   if(ptrActual==NULL)
      printf("La cola esta vacia\n");

   else{
   
		printf("La Cola es: \n");
		while(ptrActual!=NULL){ 
			/*printf("%s->",ptrActual->sDescriptorID_delPedido);
			printf("%s->",ptrActual->data);*/
			printf("%i->",ptrActual->estado);
			ptrActual=ptrActual->Sgt;  
		}
		printf("NULL \n");  
   }
   
} 




struct ListaIDdescriptors * BuscarPorNumeroSector(struct ListaIDdescriptors * ListaDeIDPedidos,int numero)		//busca un la lista de descriptores del disco por opciones: (en este el sDescriptorID_delDA que sea igual sDescriptorID, y lo saca de la lista)

{
	struct ListaIDdescriptors * pNodo;
	pNodo = ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(pNodo->numeroSector==numero)
			return pNodo;
		pNodo = pNodo->Sgt;
	}
	printf("NO SE ENCONTRO Nro Sector\n");
	return NULL;

}





int	CambiaPosicionDelNodo(struct DiscoConocido ** pnodoDisco)
{



if((ListaDiscos == NULL) || (ListaDiscos_Ult == NULL))
	return -1;


if((*pnodoDisco) != ListaDiscos_Ult )
	{
	if ((*pnodoDisco)->Ant != NULL)
		{
		(*pnodoDisco)->Ant->Sgt = (*pnodoDisco)->Sgt;
		(*pnodoDisco)->Sgt->Ant = (*pnodoDisco)->Ant;

		}
	else				/* pnodo es el primero de la lista */
		{
		(*pnodoDisco)->Sgt->Ant = NULL;
		ListaDiscos = (*pnodoDisco)->Sgt;
		}

	ListaDiscos_Ult->Sgt = (*pnodoDisco);
	(*pnodoDisco)->Ant = ListaDiscos_Ult;

	ListaDiscos_Ult = (*pnodoDisco);
	ListaDiscos_Ult->Sgt = NULL;

	}

return 0;
}
	

pedido * BuscarPendienteDeEnviar(pedido* ListaDeIDPedidos)
{
	
	pedido *pNodo = ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(pNodo->estado==0){ //Estado == 1; atendido
			return pNodo;;
		}	
		pNodo = pNodo->Sgt;
	}
	
	return NULL;
}


struct ListaIDdescriptors * BuscarPorDisco(struct ListaIDdescriptors * ListaDeIDPedidos,char* nombreDisco)		//busca un la lista de descriptores del disco por opciones: (en este el sDescriptorID_delDA que sea igual sDescriptorID, y lo saca de la lista)

{
	struct ListaIDdescriptors * pNodo;
	pNodo = ListaDeIDPedidos;

	while(pNodo != NULL)
	{
		if(!(strcmp(pNodo->discoAsignado,nombreDisco)))
			return pNodo;
		pNodo = pNodo->Sgt;
	}
	return NULL;

}

struct DiscoConocido * BuscarDiscoSinc()	
{

struct DiscoConocido * pNodo;
	
	
	pNodo = ListaDiscos;

	while(pNodo != NULL)
		{
		if(pNodo->Estado == SINCRONIZANDO)
			return pNodo;
		pNodo = pNodo->Sgt;
		}

return NULL;

}


int insertar(disco* disco1,disco* disco2){
		
	int contador=0;

	while(VectorSincronizacion[contador].discoLect != NULL){
		contador++;
	}
			
	
	VectorSincronizacion[contador].discoLect=disco1;
	VectorSincronizacion[contador].closeDiscoLect=0;
	VectorSincronizacion[contador].discoSinc=disco2;
	VectorSincronizacion[contador].closeDiscoSinc=0;
	VectorSincronizacion[contador].sectoresEnviados=0;
	VectorSincronizacion[contador].sectoresRecibidos=0;
	
	return contador;

}

void eliminar(int pos){


	VectorSincronizacion[pos].discoLect=NULL;
	VectorSincronizacion[pos].closeDiscoLect=1;
	VectorSincronizacion[pos].discoSinc=NULL;
	VectorSincronizacion[pos].closeDiscoSinc=1;
	VectorSincronizacion[pos].sectoresEnviados=0;
	VectorSincronizacion[pos].sectoresRecibidos=0;

}

void cargarVectorSincronizacion(){

	int i;
	
	for(i=0;i<10;i++){
		VectorSincronizacion[i].discoLect=NULL;
		VectorSincronizacion[i].closeDiscoLect=-1;
		VectorSincronizacion[i].discoSinc=NULL;
		VectorSincronizacion[i].closeDiscoSinc=-1;
		VectorSincronizacion[i].sectoresEnviados=0;
		VectorSincronizacion[i].sectoresRecibidos=0;
	}


}


int estaEnVecSincro(int socket){

	int i;
	int cont=0;
	
	for(i=0;i<10;i++){
		if((VectorSincronizacion[i].discoLect!=NULL)||(VectorSincronizacion[i].discoSinc!=NULL))
			cont=1;
	}
	
	if(cont){
		for(i=0;i<10;i++){
			if(VectorSincronizacion[i].discoLect!=NULL){
				if((VectorSincronizacion[i].discoSinc->iSocketHDAParaDA==socket)||(VectorSincronizacion[i].discoLect->iSocketHDAParaDA==socket))
					return 1;
			}		
		}
	}	
		
	
	return 0;
}